package com.by.hellosecurityoauth2.service.impl;

import com.by.hellosecurityoauth2.controller.request.RoleAuthorityRequestBean;
import com.by.hellosecurityoauth2.controller.request.RoleRequestBean;
import com.by.hellosecurityoauth2.domain.TRole;
import com.by.hellosecurityoauth2.domain.TRoleAuthority;
import com.by.hellosecurityoauth2.domain.repository.TRoleAuthorityRepository;
import com.by.hellosecurityoauth2.domain.repository.TRoleRepository;
import com.by.hellosecurityoauth2.service.RoleService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 白羽
 * @Date 2022-12-13 09:15:55
 */
@Service
@Transactional(value = "transactionManager", isolation = Isolation.REPEATABLE_READ,
        propagation = Propagation.REQUIRED)
public class RoleServiceImpl implements RoleService {

    private final TRoleRepository roleRepository;
    private final TRoleAuthorityRepository roleAuthorityRepository;
    
    public RoleServiceImpl(TRoleRepository roleRepository, TRoleAuthorityRepository roleAuthorityRepository) {
        this.roleRepository = roleRepository;
        this.roleAuthorityRepository = roleAuthorityRepository;
    }
    
    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public TRole findById(Long id) {
        return roleRepository.findById(id).orElse(null);
    }

    /**
     * 查询多条数据
     *
     * @param page 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Override 
    public Page<TRole> list(int page, int limit) {
        Pageable pageable = PageRequest.of(page, limit, Sort.by(Sort.Direction.DESC, "id"));
        return roleRepository.findAll((Specification<TRole>) (root, criteriaQuery, criteriaBuilder) -> {
            Predicate predicate = criteriaBuilder.conjunction();
            return predicate;
        }, pageable);
    }

    /**
     * 新增数据
     *
     * @param bean 实例对象
     * @return 实例对象
     */
    @Override
    public TRole create(RoleRequestBean bean) {
        TRole role = new TRole();
        BeanUtils.copyProperties(bean, role);
        return roleRepository.save(role);
    }

    /**
     * 修改数据
     * @param id 主键
     * @param bean 实例对象
     * @return 实例对象
     */
    @Override
    public TRole updateById(Long id, RoleRequestBean bean) {
        TRole role = findById(id);
        BeanUtils.copyProperties(bean, role);
        return roleRepository.save(role);
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     *
     */
    @Override 
    public void deleteById(Long id) {
        roleRepository.deleteById(id);
    }

    @Override
    public List<TRoleAuthority> updateRoleAuthority(Long id, List<RoleAuthorityRequestBean> bean) {
        roleAuthorityRepository.deleteByRoleId(id);
        List<TRoleAuthority> roleAuthorities = new ArrayList<>();
        for (RoleAuthorityRequestBean authority :
                bean) {
            TRoleAuthority roleAuthority = new TRoleAuthority();
            BeanUtils.copyProperties(authority, roleAuthority);
            roleAuthority.setRoleId(id);
            roleAuthorities.add(roleAuthority);
        }
        return roleAuthorityRepository.saveAll(roleAuthorities);
    }

    @Override
    public List<TRoleAuthority> getRoleAuthorityByRoleId(Long id) {
        return roleAuthorityRepository.findByRoleId(id);
    }

}